class Solution
{
private:
    int find(vector<int>& f, int x)
    {
        return f[x] == x ? x : find(f, f[x]);
    }

    void merge(vector<int>& f, int x, int y)
    {
        int fx = find(f, x), fy = find(f, y);
        f[fx] = fy;
    }

    

public:
    int regionBySlashes(vector<string>& grid)
    {
        int n = grid.size();
        vector<int> parent(n * n << 2);
        iota(parent.begin(), parent.end(), 0);

        auto addrTran = [&](int row, int col, int block)->int
        {
            return (row * n << 2) + (col << 2) + block;        //   取最上方编号为0，逆时针增加1
        };

        for (size_t cntRow = 0; cntRow < n; cntRow++)
        {
            for (size_t cntCol = 0; cntCol < n; cntCol++)
            {
                if (grid[cntRow][cntCol] == '/')
                {
                    merge(parent, addrTran(cntRow, cntCol, 0), addrTran(cntRow, cntCol, 3));
                    merge(parent, addrTran(cntRow, cntCol, 1), addrTran(cntRow, cntCol, 2));
                }
                else if (grid[cntRow][cntCol] == '\\')
                {
                    merge(parent, addrTran(cntRow, cntCol, 0), addrTran(cntRow, cntCol, 1));
                    merge(parent, addrTran(cntRow, cntCol, 2), addrTran(cntRow, cntCol, 3));
                }
                else
                {
                    merge(parent, addrTran(cntRow, cntCol, 0), addrTran(cntRow, cntCol, 1));
                    merge(parent, addrTran(cntRow, cntCol, 0), addrTran(cntRow, cntCol, 2));
                    merge(parent, addrTran(cntRow, cntCol, 0), addrTran(cntRow, cntCol, 3));
                }

                if (cntRow < n - 1)
                {
                    merge(parent, addrTran(cntRow + 1, cntCol, 0), addrTran(cntRow, cntCol, 2));
                }
                if (cntCol < n - 1)
                {
                    merge(parent, addrTran(cntRow, cntCol + 1, 3), addrTran(cntRow, cntCol, 1));
                }
            }
        }
        unordered_set<int> ret;
        for (size_t i = 0; i < n * n << 2; i++)
        {
            ret.insert(find(parent, i));
        }
        return ret.size();
    }
};